package com.childmiles.gwt.client;

import com.childmiles.gwt.client.domain.AwardWinner;
import com.childmiles.gwt.client.event.ShowAwardsEvent;
import com.childmiles.gwt.client.event.ShowAwardsEventHandler;
import com.childmiles.gwt.client.service.AwardWinnerServiceAsync;
import com.childmiles.gwt.client.ui.awards.AwardsPresenter;
import com.childmiles.gwt.client.ui.awards.AwardsView;
import com.childmiles.gwt.client.ui.login.LoginPresenter;
import com.childmiles.gwt.client.ui.login.LoginView;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.HasWidgets;

public class ApplicationController implements Presenter, ValueChangeHandler<String> {
    private final HandlerManager eventBus;

    private final AwardWinnerServiceAsync awardWinnerService;
    
    //We don't need no stinking sessions :)
    private AwardWinner currentAwardWinner;

    //Widget for our presenters to attach to
    private HasWidgets container;

    //Cached views
    private LoginView loginView;

    public ApplicationController(AwardWinnerServiceAsync awardWinnerService, HandlerManager eventBus) {
        this.awardWinnerService = awardWinnerService;
        this.eventBus = eventBus;
        History.newItem(""); //init history in case they have a token in the browser URL
        bind();
    }

    private void bind() {
        History.addValueChangeHandler(this);

        eventBus.addHandler(ShowAwardsEvent.TYPE, new ShowAwardsEventHandler() {
            public void onEvent(ShowAwardsEvent event) {
                // Set current awardWinner if necessary
                if (currentAwardWinner == null) {
                    currentAwardWinner = event.getAwardWinner();
                }
                doShowAwards();
            }
        });

    }
    
    private void doShowAwards() {
        if (currentAwardWinner == null) {
            currentAwardWinner = new AwardWinner();
        }
        History.newItem("showAwards");
    }

    public void go(final HasWidgets container) {
        this.container = container;

        if ("".equals(History.getToken())) {
            History.newItem("showLogin");
        } else {
            History.fireCurrentHistoryState();
        }
    }

    public void onValueChange(ValueChangeEvent<String> event) {
        String token = event.getValue();
        if (token == null) {
            return;
        }
        if (token.equals("showLogin")) {
            GWT.runAsync(new RunAsyncCallback() {

                public void onFailure(Throwable e) {
                    throw new RuntimeException(e);
                }

                public void onSuccess() {
                    // lazily initialize our views, and keep them around to be reused
                    if (loginView == null) {
                        loginView = new LoginView();
                    }
                    new LoginPresenter(awardWinnerService, eventBus, loginView).go(container);
                }
            });
        } 
        else if (token.equals("showAwards")) {
            GWT.runAsync(new RunAsyncCallback() {

                public void onFailure(Throwable e) {
                    throw new RuntimeException(e);
                }

                public void onSuccess() {
                    //This one can't be done lazily since it has to bind in the setDataMethod
//                    if (awardsView == null) {
//                        awardsView = new AwardsView();
//                    }
                    AwardsPresenter awardsPresenter = new AwardsPresenter(awardWinnerService, eventBus, new AwardsView());
                    awardsPresenter.setData(currentAwardWinner);
                    awardsPresenter.go(container);
                }
            });
        }
    }
}
